package cn.ivicar.mapper.service.impl;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;

import cn.ivicar.mapper.replicable.ReplicableSqlSessionFactory;
import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Inject;

public class BaseManager {
    @Inject
    protected ReplicableSqlSessionFactory sqlSessionFactory;

    /**
     * @param type
     *            The return type
     * @param sqlKey
     *            The iBatis SQL key
     * @param parameter
     *            To select with
     * @return The casted result
     * @throws SQLException
     * @throws IOException
     *             On error
     */
    @SuppressWarnings("unchecked")
    protected <T> T selectOne(Class<T> type, String sqlKey, Object parameter) {
        SqlSession session = this.sqlSessionFactory.openReplicableSqlSession(true);
        try {
            return (T) session.selectOne(sqlKey, parameter);
        } finally {
            session.close();
        }
    }

    protected Integer selectOneAsInt(String sqlKey) {
        SqlSession session = this.sqlSessionFactory.openReplicableSqlSession(true);
        try {
            return (Integer) session.selectOne(sqlKey);
        } finally {
            session.close();
        }
    }

    @SuppressWarnings("unchecked")
    protected <E> List<E> list(Class<E> type, String sqlKey) {
        SqlSession session = this.sqlSessionFactory.openReplicableSqlSession(true);
        try {
            return session.selectList(sqlKey);
        } finally {
            session.close();
        }
    }

    @SuppressWarnings("unchecked")
    protected <E> List<E> list(Class<E> type, String sqlKey, int count) {
        SqlSession session = this.sqlSessionFactory.openReplicableSqlSession(true);
        try {
            return session.selectList(sqlKey, count);
        } finally {
            session.close();
        }
    }

    @SuppressWarnings("unchecked")
    protected <E> List<E> list(Class<E> type, String sqlKey, Object parameter) {
        SqlSession session = this.sqlSessionFactory.openReplicableSqlSession(true);
        try {
            return session.selectList(sqlKey, parameter);
        } finally {
            session.close();
        }
    }

    protected void insert(String sqlKey, Object object) {
        SqlSession session = this.sqlSessionFactory.openReplicableSqlSession(false);
        try {
            session.insert(sqlKey, object);
        } finally {
            session.close();
        }
    }

    protected void update(String sqlKey, Object object) {
        SqlSession session = this.sqlSessionFactory.openReplicableSqlSession(false);
        try {
            session.update(sqlKey, object);
        } finally {
            session.close();
        }
    }

    protected void delete(String sqlKey, Object object) {
        SqlSession session = this.sqlSessionFactory.openReplicableSqlSession(false);
        try {
            session.delete(sqlKey, object);
        } finally {
            session.close();
        }
    }
}
